package com.itheima.demo;

import com.alibaba.fastjson.JSON;
import com.itheima.pojo.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 实现  document 的  实现高亮和聚合
 * @作者 itcast
 * @创建日期 2021/4/2 8:54
 **/
public class EsDemo04 {
    /**                terms
     * # 查询全部数据 先按照性别分桶  求每个分桶的年龄平均
     */
    @Test
    public void aggregations() throws IOException {
        SearchRequest request = new SearchRequest("user");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 封装聚合条件
        // 聚合条件 可以 通过工具类快速构建:  AggregationBuilders
        // AggregationBuilders: 方法的名称  就是聚合类型的名称
        //           参数:   自定义聚合名称                   聚合字段
        TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("terms_by_gender").field("gender");

        //  设置 求平均年龄的聚合条件
        AvgAggregationBuilder avgBuilder = AggregationBuilders.avg("avg_by_age").field("age");
        // 设置 先分桶 在 求平均值
        termsBuilder.subAggregation(avgBuilder);
        builder.aggregation(termsBuilder);
        request.source(builder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        // 得到全部的聚合结果
        Aggregations aggregations = searchResponse.getAggregations();
        // 根据自定义聚合处理名称 找到对应聚合处理结果
        Terms termsResult = aggregations.get("terms_by_gender");
        // 得到具体分桶信息
        List<? extends Terms.Bucket> buckets = termsResult.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            // 分桶的性别的值
            System.out.println("该分桶性别的key值: " + bucket.getKey());
            // 该分桶的人数
            System.out.println("该分桶的人数: " +bucket.getDocCount());
            // 年龄的平均值
            // 得到 该分桶下 子聚合的处理结果
            Aggregations subAggs = bucket.getAggregations();
            // 得到按照年龄求平均值的处理结果
            Avg avgResult = subAggs.get("avg_by_age");
            System.out.println("该分桶的平均年龄: " +avgResult.getValue());
        }
    }

   @Test
   public void hightQuery() throws IOException {
        SearchRequest request = new SearchRequest("user");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("note","javaee唱歌"));

        // 设置高亮条件
       HighlightBuilder highlightBuilder = new HighlightBuilder();
       highlightBuilder.field("note"); // 需要高亮显示的字段
       highlightBuilder.preTags("<span>"); // 前置标签
       highlightBuilder.postTags("</span>"); // 后置标签
       builder.highlighter(highlightBuilder);
        request.source(builder);
       SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
       SearchHits hits = searchResponse.getHits();
       SearchHit[] hitsDoc = hits.getHits();
       for (SearchHit searchHit : hitsDoc) {
           String userJson = searchHit.getSourceAsString();
           User user = JSON.parseObject(userJson, User.class);
           // 上面的user note字段并没有被高亮处理，需要去单独获取高亮的结果
           Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
           // 得到 note字段的高亮处理结果
           HighlightField noteHightResult = highlightFields.get("note");
           // note的高亮处理结果  是一个片段数组， 需要把数组中的元素拼接起来 才是一个完整的高亮结果
           Text[] fragments = noteHightResult.getFragments();
           // 得到拼接之后的高亮结果
           String noteResult = StringUtils.join(fragments);
            // 替换note字段内容
           user.setNote(noteResult);

           System.out.println(user);
       }
   }





    RestHighLevelClient client;

    /**
     * 初始化es 客户端
     */
    @Before
    public void init(){
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.200.130", 9200, "http")));


    }


    /**
     * 关闭es 客户端
     */
    @After
    public void close(){
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
